home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / include / glibmm-2.4 / glibmm / slisthandle.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-04-20  |  10.6 KB  |  406 lines

  1. // -*- c++ -*-
  2. #ifndef _GLIBMM_SLISTHANDLE_H
  3. #define _GLIBMM_SLISTHANDLE_H
  4.  
  5. /* $Id: slisthandle.h,v 1.3 2003/04/21 17:39:41 murrayc Exp $ */
  6.  
  7. /* Copyright (C) 2002 The gtkmm Development Team
  8.  *
  9.  * This library is free software; you can redistribute it and/or
  10.  * modify it under the terms of the GNU Library General Public
  11.  * License as published by the Free Software Foundation; either
  12.  * version 2 of the License, or (at your option) any later version.
  13.  *
  14.  * This library is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17.  * Library General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU Library General Public
  20.  * License along with this library; if not, write to the Free
  21.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  */
  23.  
  24. #include <glib/gslist.h>
  25. #include <glibmm/containerhandle_shared.h>
  26.  
  27.  
  28. namespace Glib
  29. {
  30.  
  31. namespace Container_Helpers
  32. {
  33.  
  34. #ifndef DOXYGEN_SHOULD_SKIP_THIS
  35.  
  36. /* Create and fill a GSList as efficient as possible.
  37.  * This requires bidirectional iterators.
  38.  */
  39. template <class Bi, class Tr>
  40. GSList* create_slist(Bi pbegin, Bi pend, Tr)
  41. {
  42.   GSList* head = 0;
  43.  
  44.   while(pend != pbegin)
  45.   {
  46.     // Use & to force a warning if the iterator returns a temporary object.
  47.     const void *const item = Tr::to_c_type(*&*--pend);
  48.     head = g_slist_prepend(head, const_cast<void*>(item));
  49.   }
  50.  
  51.   return head;
  52. }
  53.  
  54. /* Create a GSList from a 0-terminated input sequence.
  55.  * Build it in reverse order and reverse the whole list afterwards,
  56.  * because appending to the list would be horribly inefficient.
  57.  */
  58. template <class For, class Tr>
  59. GSList* create_slist(For pbegin, Tr)
  60. {
  61.   GSList* head = 0;
  62.  
  63.   while(*pbegin)
  64.   {
  65.     // Use & to force a warning if the iterator returns a temporary object.
  66.     const void *const item = Tr::to_c_type(*&*pbegin);
  67.     head = g_slist_prepend(head, const_cast<void*>(item));
  68.     ++pbegin;
  69.   }
  70.  
  71.   return g_slist_reverse(head);
  72. }
  73.  
  74.  
  75. /* Convert from any container that supports bidirectional iterators.
  76.  */
  77. template <class Tr, class Cont>
  78. struct SListSourceTraits
  79. {
  80.   static GSList* get_data(const Cont& cont)
  81.     { return Glib::Container_Helpers::create_slist(cont.begin(), cont.end(), Tr()); }
  82.  
  83.   static const Glib::OwnershipType initial_ownership = Glib::OWNERSHIP_SHALLOW;
  84. };
  85.  
  86. /* Convert from a 0-terminated array.  The Cont
  87.  * argument must be a pointer to the first element.
  88.  */
  89. template <class Tr, class Cont>
  90. struct SListSourceTraits<Tr,Cont*>
  91. {
  92.   static GSList* get_data(const Cont* array)
  93.     { return (array) ? Glib::Container_Helpers::create_slist(array, Tr()) : 0; }
  94.  
  95.   static const Glib::OwnershipType initial_ownership = Glib::OWNERSHIP_SHALLOW;
  96. };
  97.  
  98. template <class Tr, class Cont>
  99. struct SListSourceTraits<Tr,const Cont*> : SListSourceTraits<Tr,Cont*>
  100. {};
  101.  
  102. /* Convert from a 0-terminated array.  The Cont argument must be a pointer
  103.  * to the first element.  For consistency, the array must be 0-terminated,
  104.  * even though the array size is known at compile time.
  105.  */
  106. template <class Tr, class Cont, size_t N>
  107. struct SListSourceTraits<Tr,Cont[N]>
  108. {
  109.   static GSList* get_data(const Cont* array)
  110.     { return Glib::Container_Helpers::create_slist(array, array + (N - 1), Tr()); }
  111.  
  112.   static const Glib::OwnershipType initial_ownership = Glib::OWNERSHIP_SHALLOW;
  113. };
  114.  
  115. template <class Tr, class Cont, size_t N>
  116. struct SListSourceTraits<Tr,const Cont[N]> : SListSourceTraits<Tr,Cont[N]>
  117. {};
  118.  
  119. #endif /* DOXYGEN_SHOULD_SKIP_THIS */
  120.  
  121.  
  122. /**
  123.  * @ingroup ContHelpers
  124.  * If a method takes this as an argument, or has this as a return type, then you can use a standard
  125.  * container such as std::list or std::vector.
  126.  */
  127. template <class Tr>
  128. class SListHandleIterator
  129. {
  130. public:
  131.   typedef typename Tr::CppType        CppType;
  132.   typedef typename Tr::CType          CType;
  133.  
  134.   typedef std::forward_iterator_tag   iterator_category;
  135.   typedef CppType                     value_type;
  136.   typedef ptrdiff_t                   difference_type;
  137.   typedef value_type                  reference;
  138.   typedef void                        pointer;
  139.  
  140.   explicit inline SListHandleIterator(const GSList* node);
  141.  
  142.   inline value_type                    operator*() const;
  143.   inline SListHandleIterator<Tr> &     operator++();
  144.   inline const SListHandleIterator<Tr> operator++(int);
  145.  
  146.   inline bool operator==(const SListHandleIterator<Tr>& rhs) const;
  147.   inline bool operator!=(const SListHandleIterator<Tr>& rhs) const;
  148.  
  149. private:
  150.   const GSList* node_;
  151. };
  152.  
  153. } // namespace Container_Helpers
  154.  
  155.  
  156. /**
  157.  * @ingroup ContHandles
  158.  */
  159. template < class T, class Tr = Glib::Container_Helpers::TypeTraits<T> >
  160. class SListHandle
  161. {
  162. public:
  163.   typedef typename Tr::CppType  CppType;
  164.   typedef typename Tr::CType    CType;
  165.  
  166.   typedef CppType               value_type;
  167.   typedef size_t                size_type;
  168.   typedef ptrdiff_t             difference_type;
  169.  
  170.   typedef Glib::Container_Helpers::SListHandleIterator<Tr>   const_iterator;
  171.   typedef Glib::Container_Helpers::SListHandleIterator<Tr>   iterator;
  172.  
  173.   template <class Cont> inline
  174.     SListHandle(const Cont& container);
  175.  
  176.   // Take over ownership of a GSList created by GTK+ functions.
  177.   inline SListHandle(GSList* glist, Glib::OwnershipType ownership);
  178.  
  179.   // Copying clears the ownership flag of the source handle.
  180.   inline SListHandle(const SListHandle<T,Tr>& other);
  181.  
  182.   ~SListHandle();
  183.  
  184.   inline const_iterator begin() const;
  185.   inline const_iterator end()   const;
  186.  
  187.   template <class U> inline operator std::vector<U>() const;
  188.   template <class U> inline operator std::deque<U>()  const;
  189.   template <class U> inline operator std::list<U>()   const;
  190.  
  191.   template <class Cont> inline
  192.     void assign_to(Cont& container) const;
  193.   template <class Out> inline
  194.     void copy(Out pdest) const;
  195.  
  196.   inline GSList* data()  const;
  197.   inline size_t  size()  const;
  198.   inline bool    empty() const;
  199.  
  200. private:
  201.   GSList *                    pslist_;
  202.   mutable Glib::OwnershipType ownership_;
  203.  
  204.   // No copy assignment.
  205.   SListHandle<T,Tr>& operator=(const SListHandle<T,Tr>&);
  206. };
  207.  
  208.  
  209. /***************************************************************************/
  210. /*  Inline implementation                                                  */
  211. /***************************************************************************/
  212.  
  213. #ifndef DOXYGEN_SHOULD_SKIP_THIS
  214.  
  215. namespace Container_Helpers
  216. {
  217.  
  218. /**** Glib::Container_Helpers::SListHandleIterator<> ***********************/
  219.  
  220. template <class Tr> inline
  221. SListHandleIterator<Tr>::SListHandleIterator(const GSList* node)
  222. :
  223.   node_ (node)
  224. {}
  225.  
  226. template <class Tr> inline
  227. typename SListHandleIterator<Tr>::value_type SListHandleIterator<Tr>::operator*() const
  228. {
  229.   return Tr::to_cpp_type(static_cast<typename Tr::CTypeNonConst>(node_->data));
  230. }
  231.  
  232. template <class Tr> inline
  233. SListHandleIterator<Tr>& SListHandleIterator<Tr>::operator++()
  234. {
  235.   node_ = node_->next;
  236.   return *this;
  237. }
  238.  
  239. template <class Tr> inline
  240. const SListHandleIterator<Tr> SListHandleIterator<Tr>::operator++(int)
  241. {
  242.   const SListHandleIterator<Tr> tmp (*this);
  243.   node_ = node_->next;
  244.   return tmp;
  245. }
  246.  
  247. template <class Tr> inline
  248. bool SListHandleIterator<Tr>::operator==(const SListHandleIterator<Tr>& rhs) const
  249. {
  250.   return (node_ == rhs.node_);
  251. }
  252.  
  253. template <class Tr> inline
  254. bool SListHandleIterator<Tr>::operator!=(const SListHandleIterator<Tr>& rhs) const
  255. {
  256.   return (node_ != rhs.node_);
  257. }
  258.  
  259. } // namespace Container_Helpers
  260.  
  261.  
  262. /**** Glib::SListHandle<> **************************************************/
  263.  
  264. template <class T, class Tr>
  265.   template <class Cont>
  266. inline
  267. SListHandle<T,Tr>::SListHandle(const Cont& container)
  268. :
  269.   pslist_    (Glib::Container_Helpers::SListSourceTraits<Tr,Cont>::get_data(container)),
  270.   ownership_ (Glib::Container_Helpers::SListSourceTraits<Tr,Cont>::initial_ownership)
  271. {}
  272.  
  273. template <class T, class Tr> inline
  274. SListHandle<T,Tr>::SListHandle(GSList* gslist, Glib::OwnershipType ownership)
  275. :
  276.   pslist_    (gslist),
  277.   ownership_ (ownership)
  278. {}
  279.  
  280. template <class T, class Tr> inline
  281. SListHandle<T,Tr>::SListHandle(const SListHandle<T,Tr>& other)
  282. :
  283.   pslist_    (other.pslist_),
  284.   ownership_ (other.ownership_)
  285. {
  286.   other.ownership_ = Glib::OWNERSHIP_NONE;
  287. }
  288.  
  289. template <class T, class Tr>
  290. SListHandle<T,Tr>::~SListHandle()
  291. {
  292.   if(ownership_ != Glib::OWNERSHIP_NONE)
  293.   {
  294.     if(ownership_ != Glib::OWNERSHIP_SHALLOW)
  295.     {
  296.       // Deep ownership: release each container element.
  297.       for(GSList* node = pslist_; node != 0; node = node->next)
  298.         Tr::release_c_type(static_cast<typename Tr::CTypeNonConst>(node->data));
  299.     }
  300.     g_slist_free(pslist_);
  301.   }
  302. }
  303.  
  304. template <class T, class Tr> inline
  305. typename SListHandle<T,Tr>::const_iterator SListHandle<T,Tr>::begin() const
  306. {
  307.   return Glib::Container_Helpers::SListHandleIterator<Tr>(pslist_);
  308. }
  309.  
  310. template <class T, class Tr> inline
  311. typename SListHandle<T,Tr>::const_iterator SListHandle<T,Tr>::end() const
  312. {
  313.   return Glib::Container_Helpers::SListHandleIterator<Tr>(0);
  314. }
  315.  
  316. template <class T, class Tr>
  317.   template <class U>
  318. inline
  319. SListHandle<T,Tr>::operator std::vector<U>() const
  320. {
  321. #ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
  322.   return std::vector<U>(this->begin(), this->end());
  323. #else
  324.   std::vector<U> temp;
  325.   temp.reserve(this->size());
  326.   Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
  327.   return temp;
  328. #endif
  329. }
  330.  
  331. template <class T, class Tr>
  332.   template <class U>
  333. inline
  334. SListHandle<T,Tr>::operator std::deque<U>() const
  335. {
  336. #ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
  337.   return std::deque<U>(this->begin(), this->end());
  338. #else
  339.   std::deque<U> temp;
  340.   Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
  341.   return temp;
  342. #endif
  343. }
  344.  
  345. template <class T, class Tr>
  346.   template <class U>
  347. inline
  348. SListHandle<T,Tr>::operator std::list<U>() const
  349. {
  350. #ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
  351.   return std::list<U>(this->begin(), this->end());
  352. #else
  353.   std::list<U> temp;
  354.   Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
  355.   return temp;
  356. #endif
  357. }
  358.  
  359. template <class T, class Tr>
  360.   template <class Cont>
  361. inline
  362. void SListHandle<T,Tr>::assign_to(Cont& container) const
  363. {
  364. #ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
  365.   container.assign(this->begin(), this->end());
  366. #else
  367.   Cont temp;
  368.   Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
  369.   container.swap(temp);
  370. #endif
  371. }
  372.  
  373. template <class T, class Tr>
  374.   template <class Out>
  375. inline
  376. void SListHandle<T,Tr>::copy(Out pdest) const
  377. {
  378.   std::copy(this->begin(), this->end(), pdest);
  379. }
  380.  
  381. template <class T, class Tr> inline
  382. GSList* SListHandle<T,Tr>::data() const
  383. {
  384.   return pslist_;
  385. }
  386.  
  387. template <class T, class Tr> inline
  388. size_t SListHandle<T,Tr>::size() const
  389. {
  390.   return g_slist_length(pslist_);
  391. }
  392.  
  393. template <class T, class Tr> inline
  394. bool SListHandle<T,Tr>::empty() const
  395. {
  396.   return (pslist_ == 0);
  397. }
  398.  
  399. #endif /* DOXYGEN_SHOULD_SKIP_THIS */
  400.  
  401. } // namespace Glib
  402.  
  403.  
  404. #endif /* _GLIBMM_SLISTHANDLE_H */
  405.  
  406.